package main

import (
	"bufio"
	"fmt"
	"os/exec"
	"strings"
	"time"
)

func Handle(dirName, appName, cmd string) {
	pid, _ := CheckProRunning(`go build -o .\/` + appName)
	fmt.Println("--- process `go build` pid: ", pid)
	if pid == "" {
		_, err := RunCommand("go build -o ./" + appName)
		if err == nil {
			pid, _ := CheckProRunning("\\/" + appName)
			if pid != "" {
				fmt.Println("--- kill " + appName + " process: " + pid)
				RunCommand("kill " + pid)
			}
			//go func() {
			/*pid, _ = CheckProRunning("goflush.sh")
			fmt.Println(pid, "****")
			if pid != "" {
				fmt.Println("kill sh goflush.sh process: ", pid)
				RunCommand("kill " + pid)
			}*/
			result, _ := GetOutputContinually(appName)
			<-result
			//}()
		}
		if err != nil {
			fmt.Println(err)
			return
		}
	} else {
		fmt.Println("--- " + time.Now().Format("2006-01-02 15:04:05") + " last build process is running, please waiting")
	}

}

//根据进程名判断进程是否运行
func CheckProRunning(serverName string) (string, error) {
	/*b := `ps ux | awk '/(` + serverName + `$)|(` + serverName + ` +)/'`

	t, _ := RunCommand(b)
	fmt.Println(t, b, "%%%%%%%%%")*/
	a := `ps ux | awk '/(` + serverName + `$)|(` + serverName + ` +)/ && !/awk/ {print $2}'`
	pid, err := RunCommand(a)
	//fmt.Println(a, pid, "&&&&&&&&")
	if err != nil {
		return "", err
	}
	return pid, nil
}

//根据进程名称获取进程ID
func GetPid(serverName string) (string, error) {
	a := `ps ux | awk '/` + serverName + `/ && !/awk/ {print $2}'`
	pid, err := RunCommand(a)
	return pid, err
}

//在命令执行结束后获得系统输出结果
func RunCommand(script string) (string, error) {
	cmd := exec.Command("/bin/sh", "-c", script)
	//cmd := exec.Command(script)
	//fmt.Println(script, "##########")
	result, err := cmd.CombinedOutput()
	if err != nil {
		fmt.Println("\"", script, "\" error: ")
		fmt.Println("result: ", string(result))
		fmt.Println("error: ", err)
		return strings.TrimSpace(string(result)), err
	}
	return strings.TrimSpace(string(result)), nil
}

//在命令执行过程中获得系统输出信息
func GetOutputContinually(appName string) (<-chan struct{}, error) {
	cmd := exec.Command("sh", appName+`_goflush.sh`)
	fmt.Println("--- "+time.Now().Format("2006-01-02 15:04:05"), appName+" start")
	closed := make(chan struct{})
	defer close(closed)

	stdoutPipe, err := cmd.StdoutPipe()
	if err != nil {
		fmt.Println(err)
		return closed, err
	}
	defer stdoutPipe.Close()

	stderrPipe, err := cmd.StderrPipe()
	if err != nil {
		fmt.Println(err)
		return closed, err
	}
	defer stderrPipe.Close()

	go func() {
		scanner := bufio.NewScanner(stdoutPipe)
		scanner2 := bufio.NewScanner(stderrPipe)
		for scanner.Scan() || scanner2.Scan() {
			// 命令在执行的过程中, 实时地获取其输出
			if len(scanner.Bytes()) > 0 {
				fmt.Printf("%s\n", string(scanner.Bytes()))
			}
			if len(scanner2.Bytes()) > 0 {
				fmt.Printf("%s\n", string(scanner2.Bytes()))
			}
		}
	}()
	if err := cmd.Run(); err != nil {
		pid, _ := CheckProRunning(appName + `_goflush.sh`)
		if pid == "" {
			fmt.Println(err, cmd)
		} else {
			fmt.Println("--- " + appName + " is running ... ")
		}
	}
	return closed, nil
}
